#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.setup.utils;

import ${package}.common.bean.po.Code;
import ${package}.common.bean.po.CodeType;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.util.Assert;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;

/**
 * Description: 为code生成源代码
 *
 * @author wenxiaopeng
 * @date 2021/06/21 13:07
 *
 * <pre>
 *              ${copyright}
 *      Copyright (c) 2021. All Rights Reserved.
 * </pre>
 */
public class SourceCodeUtil {

	private static final String CLASS_HEADER = "/** %s */${symbol_escape}npublic class %s {";
	private static final String ENUM_HEADER = "/** %s */${symbol_escape}npublic enum %s {";
	private static final String VUE_JS_HEADER = "/** %s */${symbol_escape}nVue.prototype.%s = function (val) {${symbol_escape}n" +
			"${symbol_escape}tswitch (val) {${symbol_escape}n";
	private static final String CLOSE = "}";
	private static final String COMMENT = "${symbol_escape}t/** %s */${symbol_escape}n";
	private static final String DESCRIPTOR_CONSTANT = "${symbol_escape}tpublic static final String %s = ${symbol_escape}"%s${symbol_escape}";${symbol_escape}n";
	private static final String DESCRIPTOR_ENUM = "${symbol_escape}t%s(${symbol_escape}"%s${symbol_escape}", ${symbol_escape}"%s${symbol_escape}"),";
	private static final String DESCRIPTOR_JS = "${symbol_escape}t${symbol_escape}tcase '%s':${symbol_escape}n" +
			"${symbol_escape}t${symbol_escape}t${symbol_escape}treturn '%s';${symbol_escape}n";
	private static final String ENUM_CONSTRUCTOR = "${symbol_escape}n    ;${symbol_escape}n" +
			"    private String code;${symbol_escape}n" +
			"    private String value;${symbol_escape}n" +
			"${symbol_escape}n" +
			"    %s(String code, String value) {${symbol_escape}n" +
			"        this.code = code;${symbol_escape}n" +
			"        this.value = value;${symbol_escape}n" +
			"    }${symbol_escape}n" +
			"${symbol_escape}n" +
			"    public String getCode() {${symbol_escape}n" +
			"        return code;${symbol_escape}n" +
			"    }${symbol_escape}n" +
			"${symbol_escape}n" +
			"    public String getValue() {${symbol_escape}n" +
			"        return value;${symbol_escape}n" +
			"    }${symbol_escape}n";
	/**
	 * Description:
	 * <>
	 * @param codeType 1
	 * @param codes 2
	 * @param style 代码风格
	 * @author wenxiaopeng
	 * @date 13:09 2021/06/21
	 * @return java.lang.String
	 **/
	public static File getSourceCode(CodeType codeType, List<Code> codes, CodeStyle style) {
		Assert.notNull(codeType, "代码类型不可为空");
		String source;
		String fileName = codeType.getCodeType();

		switch (style) {
			case CLASS:
				source = buildClass(codeType, codes);
				fileName = fileName + ".java";
				break;
			case JS:
				source = buildJavaScript(codeType, codes);
				fileName = fileName + ".js";
				break;
			case ENUM:
			default:
				source = buildEnum(codeType, codes);
				fileName = fileName + ".java";
		}
		File file = new File(fileName);
		try (FileWriter fw = new FileWriter(file);
		     BufferedWriter out = new BufferedWriter(fw)) {
			out.write(source);
		} catch (Exception e) {

		}
		return file;
	}

	/**
	 * Description:
	 * <生成enum风格的代码>
	 * @param codeType 1
	 * @param codes 2
	 * @author wenxiaopeng
	 * @date 13:39 2021/06/21
	 * @return java.lang.String
	 **/
	private static String buildEnum(CodeType codeType, List<Code> codes) {
		String className = adjustClassName(codeType.getCodeType());
		StringBuffer sb = new StringBuffer(String.format(ENUM_HEADER, codeType.getDescription(), className));
		codes.forEach(code -> {
			sb.append("${symbol_escape}n");
			sb.append(String.format(COMMENT, code.getValue()));
			String field = code.getCode();
			if(NumberUtils.isDigits(field.substring(0,1))) {
				field = "E" + field;
			}
			field = field.toUpperCase().replaceAll("-", "_");
			sb.append(String.format(DESCRIPTOR_ENUM, field, code.getCode(), code.getValue()));
		});
		// 构造函数
		sb.append(String.format(ENUM_CONSTRUCTOR, className));

		// 结束
		sb.append(CLOSE);
		return sb.toString();
	}

	/**
	 * Description:
	 * <调整类名>
	 * @param codeType 1
	 * @author wenxiaopeng
	 * @date 12:04 2021/06/22
	 * @return java.lang.String
	 **/
	private static String adjustClassName(String codeType) {
		codeType = codeType.replaceAll("-", "_");
		if (NumberUtils.isDigits(codeType.substring(0, 1))) {
			codeType = "CT" + codeType;
		}
		return codeType;
	}

//	/**
//	 * @author: xinyue
//	 * @description: 任务状态
//	 * @param {}: 0-待分配 1-进行中 2-已完成 9-已作废
//	 */
//	Vue.prototype.taskStatusColor = function (val) {
//		switch (val) {
//			case '已作废':
//				return 'invalidsStatus';
//			case '待分配':
//				return 'allocatsStatus';
//			case '进行中':
//				return 'haveinhsStatus';
//			case '已完成':
//				return 'completsStatus';
//			default:
//				return 'invalidsStatus';
//		}
//	};
	private static String buildJavaScript(CodeType codeType, List<Code> codes) {
		String className = adjustClassName(codeType.getCodeType());
		StringBuffer sb = new StringBuffer(String.format(VUE_JS_HEADER, codeType.getDescription(), className));
		codes.forEach(code -> {
			sb.append(String.format(DESCRIPTOR_JS, code.getCode(), code.getValue()));
		});
		// 结束
		sb.append("${symbol_escape}t${symbol_escape}tdefault:${symbol_escape}n${symbol_escape}t${symbol_escape}t${symbol_escape}treturn '';${symbol_escape}n${symbol_escape}t}${symbol_escape}n");
		sb.append(CLOSE);
		return sb.toString();
	}

	/**
	 * Description:
	 * <生成常量类风格的代码>
	 * @param codeType 1
	 * @param codes 2
	 * @author wenxiaopeng
	 * @date 13:39 2021/06/21
	 * @return java.lang.String
	 **/
	private static String buildClass(CodeType codeType, List<Code> codes) {
		String className = adjustClassName(codeType.getCodeType());
		StringBuffer sb = new StringBuffer(String.format(CLASS_HEADER, codeType.getDescription(), className));
		codes.forEach(code -> {
			sb.append("${symbol_escape}n");
			sb.append(String.format(COMMENT, code.getValue()));
			String field = code.getCode();
			if(NumberUtils.isDigits(field.substring(0,1))) {
				field = "C" + field;
			}
			sb.append(String.format(DESCRIPTOR_CONSTANT, field.toUpperCase().replaceAll("-", "_"), code.getCode()));
		});
		// 结束
		sb.append(CLOSE);
		return sb.toString();
	}

	public enum CodeStyle {
		/** 下载的java代码类型 */
		CLASS,
		ENUM,
		JS
	}
}
